package net.siufung.simple.config.exception;

import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;
import net.siufung.core.exception.BizServiceException;
import net.siufung.core.exception.SiufungServiceException;
import net.siufung.core.result.Result;
import net.siufung.core.result.ResultFail;
import net.siufung.core.utils.ValidationUtil;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.util.List;
import java.util.Map;

/**
 * 统一异常控制器
 * @author 陈建峰
 * @since 2022/4/24 4:38 下午
 */
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {

    /**
     * GlobalException 异常处理
     * @param globalException 异常格式
     * @return Result<Map<String,Object>>
     */
    @ExceptionHandler(value = Exception.class)
    public Result<Map<String,Object>> globalException(Exception globalException) {
        String exceptionMessage = globalException.getMessage();
        if(StrUtil.isBlank(exceptionMessage)){
            exceptionMessage = ResultFail.ERROR.getMessage();
        }
        log.error("【GlobalException】: {}", exceptionMessage);
        return Result.fail(exceptionMessage);
    }

    /**
     * AccessDeniedException 拒绝访问异常
     * @param accessDeniedException 绝访问异常
     * @return Result<Map<String,Object>>
     */
    @ExceptionHandler(value = AccessDeniedException.class)
    public Result<Map<String,Object>> globalException(AccessDeniedException accessDeniedException) {
        String exceptionMessage = accessDeniedException.getMessage();
        if(StrUtil.isBlank(exceptionMessage)){
            exceptionMessage = ResultFail.AUTH_ACCESS_DENIED.getMessage();
        }
        log.error("【AccessDeniedException】: {}", exceptionMessage);
        return Result.fail(exceptionMessage);
    }

    /**
     * BizServiceException 异常处理
     * @param bizServiceException 异常格式
     * @return Result<Map<String,Object>>
     */
    @ExceptionHandler(value = BizServiceException.class)
    public Result<Map<String,Object>> bizServiceException(BizServiceException bizServiceException) {
        String exceptionMessage = bizServiceException.getMessage();
        if(StrUtil.isBlank(exceptionMessage)){
            exceptionMessage = ResultFail.ERROR.getMessage();
        }
        log.error("【BizServiceException】: {}", exceptionMessage);
        return Result.fail(exceptionMessage);
    }

    /**
     * SiufungServiceException 异常处理
     * @param siufungServiceException 异常格式
     * @return Result<Map<String,Object>>
     */
    @ExceptionHandler(value = SiufungServiceException.class)
    public Result<Map<String,Object>> defaultServiceException(SiufungServiceException siufungServiceException) {
        String exceptionMessage = siufungServiceException.getMessage();
        if(StrUtil.isBlank(exceptionMessage)){
            exceptionMessage = ResultFail.ERROR.getMessage();
        }
        log.error("【SiufungServiceException】: {}", exceptionMessage);
        return Result.fail(exceptionMessage);
    }

    /**
     * 请求参数统一异常
     * @param methodArgumentNotValidException 方法参数不能验证通过异常
     * @return Result<String>
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public Result<String> validationBodyException(MethodArgumentNotValidException methodArgumentNotValidException){
        ValidationUtil.ValidResult validResult = new ValidationUtil.ValidResult();
        BindingResult result  = methodArgumentNotValidException.getBindingResult();
        if (result.hasErrors()) {
            List<ObjectError> errors = result.getAllErrors();
            errors.forEach(error -> {
                FieldError fieldError = (FieldError) error;
                validResult.addError(fieldError.getObjectName(), fieldError.getDefaultMessage());
            });
            log.error(ResultFail.PARAM_VALID_ERROR.getMessage() + ":" + validResult.getErrors()+"");
        }
        return  Result.fail(ResultFail.PARAM_VALID_ERROR.getMessage() + ":" + validResult.getErrors()+"");
    }

//    /**
//     * 404异常捕获
//     * @param noHandlerFoundException 404异常
//     * @return Result<Map<String,Object>>
//     */
//    @ExceptionHandler(NoHandlerFoundException.class)
//    public Result<Map<String,Object>> handleNoHandlerFoundException(NoHandlerFoundException noHandlerFoundException){
//        String exceptionMessage = noHandlerFoundException.getMessage();
//        if(StrUtil.isBlank(exceptionMessage)){
//            exceptionMessage = ResultFail.RESOURCE_NOT_FOUND_ERROR.getMessage();
//        }
//        log.error("【NoHandlerFoundException】: {}", exceptionMessage);
//        return Result.fail(exceptionMessage);
//    }

}
